package com.xinou.daily_report.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinou.common.base.config.ApiResponse;
import com.xinou.common.base.exception.BusException;
import com.xinou.common.enumerate.HttpStatusEnum;
import com.xinou.common.util.BeanUtil;
import com.xinou.daily_report.PO.WeekResultPO;
import com.xinou.daily_report.PO.WeekResultUpdateSinglePO;
import com.xinou.daily_report.PO.WeekResultUpdatePO;
import com.xinou.daily_report.VO.WeekPlanInfoVO;
import com.xinou.daily_report.VO.WeekResultInfoVO;
import com.xinou.daily_report.entity.*;
import com.xinou.daily_report.entity.SysWeekResult;
import com.xinou.daily_report.mapper.SysWeekResultMapper;
import com.xinou.daily_report.service.SysWeekResultService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinou.daily_report.service.SysWeekTimeService;
import com.xinou.sso.service.SysUserService;
import com.xinou.sso.util.ShiroUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.*;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2021-06-11
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysWeekResultServiceImpl extends ServiceImpl<SysWeekResultMapper, SysWeekResult> implements SysWeekResultService {
    private final SysWeekTimeService sysWeekTimeService;

    private final SysUserService sysUserService;
    private final SysWeekResultMapper sysWeekResultMapper;


    @Override
    public ApiResponse weekResultList(WeekResultPO po) {
        LocalDateTime now = LocalDateTime.now();
        po.setSelectTime(now);
        Page<WeekResultPO> page = new Page<>(po.getPageNumber(), po.getPageSize());
        Page<WeekResultInfoVO> weekResultInfoVOPage = sysWeekResultMapper.weekResultMapperList(page,po);
        return new ApiResponse<>(weekResultInfoVOPage.getRecords(),weekResultInfoVOPage.getTotal());
        }


        @Override
        public ApiResponse<Void> weekResultSave (WeekResultUpdatePO weekResultUpdatePO){
            //先找到本周的weekId
            LocalDateTime now = LocalDateTime.now();
            Long weekTimeId = 0L;
            SysWeekTime sysWeekTimeServiceOne = sysWeekTimeService.getOne(new LambdaQueryWrapper<SysWeekTime>()
                        .le( SysWeekTime::getBeginTime, now)
                        .ge( SysWeekTime::getEndTime, now));


            if (sysWeekTimeServiceOne==null){
                //添加之前先判断当前时间是否存在不在的话向时间表里插入一个数据
                Date from = Date.from(Instant.now());
                DateTime begin = DateUtil.beginOfWeek(from);
                DateTime end = DateUtil.endOfWeek(from);
                Instant beginInstant = begin.toInstant();
                ZoneId beginZoneId = ZoneId.systemDefault();
                Instant endInstant = end.toInstant();
                ZoneId endZoneId = ZoneId.systemDefault();
                LocalDateTime beginLocalDateTime = LocalDateTime.ofInstant(beginInstant, beginZoneId);
                LocalDateTime endLocalDateTime = LocalDateTime.ofInstant(endInstant, endZoneId);
                //这周设置下周的时间
//            LocalDateTime begin1 = beginLocalDateTime.plusWeeks(1L);
//            LocalDateTime end1 = endLocalDateTime.plusWeeks(1L);
                SysWeekTime sysWeekTime = new SysWeekTime();
                sysWeekTime.setBeginTime(beginLocalDateTime);
                LocalDateTime time = beginLocalDateTime.plusDays(6L).plusHours(23).plusMinutes(59).plusSeconds(59);
                sysWeekTime.setEndTime(time);
//                sysWeekTime.setEndTime(endLocalDateTime);
                sysWeekTimeService.save(sysWeekTime);
                sysWeekTimeServiceOne = sysWeekTimeService.getOne(new LambdaQueryWrapper<SysWeekTime>()
                        .le( SysWeekTime::getBeginTime, now)
                        .ge( SysWeekTime::getEndTime, now));
            }
            weekTimeId=sysWeekTimeServiceOne.getId();

            if(count(new LambdaQueryWrapper<SysWeekResult>()
            .eq(SysWeekResult::getWeekId,sysWeekTimeServiceOne.getId())
                    .eq(SysWeekResult::getUserId,ShiroUtil.getUserId())
            )>0){
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "您本周已经添加过了，请勿重复添加");
            }


            List<WeekResultUpdateSinglePO> weekResultPOList = weekResultUpdatePO.getWeekResultPOList();
            if (weekResultPOList.isEmpty()) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周结果不能为空");
            }
            if (weekResultPOList.size() > 20) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周结果长度最大为20");
            }
            for (WeekResultUpdateSinglePO weekResultPO : weekResultPOList) {
                if (weekResultPO.getResultType() == null) {
                    throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "所有周结果的事项都不能为空");
                }
                weekResultPO.setUserId(ShiroUtil.getUserId());
                weekResultPO.setWeekId(weekTimeId);
                weekResultPO.setInsertTime(LocalDateTime.now());
            }
            saveBatch(BeanUtil.listA2ListB(weekResultPOList,SysWeekResult.class));
            return new ApiResponse<>();
        }


        @Override
        public ApiResponse<Void> weekResultUpdate (WeekResultUpdatePO weekResultUpdatePO){
            Long userId = weekResultUpdatePO.getUserId();
            Long weekTimeId = weekResultUpdatePO.getWeekId();
            //先找到本周的weekId
            LocalDateTime now = LocalDateTime.now();
            SysWeekTime sysWeekTimeServiceOne = sysWeekTimeService.getById(weekTimeId);
            if (sysWeekTimeServiceOne.getEndTime().isBefore(now)
            ) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "历史记录已经存档，不能进行修改");
            }

            List<WeekResultUpdateSinglePO> weekResultPOList = weekResultUpdatePO.getWeekResultPOList();
            if (weekResultPOList.isEmpty()) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周结果不能为空");
            }
            if (weekResultPOList.size() > 20) {
                throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "周结果长度最大为20");
            }
            for (WeekResultUpdateSinglePO weekResultPO : weekResultPOList) {
                if (weekResultPO.getResultType() == null) {
                    throw new BusException(HttpStatusEnum.RE_CODE_DATABASE_ERROR, "所有周结果的事项都不能为空");
                }
                weekResultPO.setUserId(userId);
                weekResultPO.setWeekId(weekTimeId);
                weekResultPO.setInsertTime(LocalDateTime.now());
            }


            remove(new LambdaQueryWrapper<SysWeekResult>().
                    eq(SysWeekResult::getWeekId,weekTimeId)
                    .eq(SysWeekResult::getUserId,userId)
            );
            saveBatch(BeanUtil.listA2ListB(weekResultPOList, SysWeekResult.class));
            return new ApiResponse<>();
        }

        @Override
        public ApiResponse<Void> weekResultDelete (WeekResultPO weekResultPO){
            Long userId = weekResultPO.getUserId();
            Long weekTimeId = weekResultPO.getWeekId();
            remove(new LambdaQueryWrapper<SysWeekResult>().
                    eq(SysWeekResult::getWeekId,weekTimeId)
                    .eq(SysWeekResult::getUserId,userId)
            );
            return new ApiResponse<>();
        }


        @Override
        public ApiResponse<WeekResultInfoVO> weekResultGetById (WeekResultPO weekResultPO){
            Long userId = weekResultPO.getUserId();
            Long weekTimeId = weekResultPO.getWeekId();
            SysWeekTime byId1 = sysWeekTimeService.getById(weekTimeId);
            Page<SysWeekResult> page = new Page<>(weekResultPO.getPageNumber(), weekResultPO.getPageSize());
            Page<SysWeekResult> sysWeekResultPage = page(page, new LambdaQueryWrapper<SysWeekResult>()
                    .eq(SysWeekResult::getUserId, userId)
                    .eq(SysWeekResult::getWeekId, weekTimeId)
                    .orderByDesc(SysWeekResult::getInsertTime)
            );
            List<SysWeekResult> list = sysWeekResultPage.getRecords();
            WeekResultInfoVO weekResultInfoVO = new WeekResultInfoVO();
            weekResultInfoVO.setWeekResultInfoVOList(BeanUtil.listA2ListB(list, WeekResultInfoVO.class));
            weekResultInfoVO.setBeginTime(byId1.getBeginTime());
            weekResultInfoVO.setEndTime(byId1.getEndTime());
            return new ApiResponse<WeekResultInfoVO>(Collections.singleton(weekResultInfoVO), sysWeekResultPage.getTotal());

        }

        @Override
        public ApiResponse<WeekResultInfoVO> weekResultGetByIdNoPaging (WeekResultPO weekResultPO){
            Long userId = weekResultPO.getUserId();
            Long weekTimeId = weekResultPO.getWeekId();
            SysWeekTime byId1 = sysWeekTimeService.getById(weekTimeId);
            List<SysWeekResult> list = list(new LambdaQueryWrapper<SysWeekResult>()
                    .eq(SysWeekResult::getUserId, userId)
                    .eq(SysWeekResult::getWeekId, weekTimeId)
                    .orderByDesc(SysWeekResult::getInsertTime)
            );
            WeekResultInfoVO weekResultInfoVO = new WeekResultInfoVO();
            weekResultInfoVO.setWeekResultInfoVOList(BeanUtil.listA2ListB(list, WeekResultInfoVO.class));
            weekResultInfoVO.setBeginTime(byId1.getBeginTime());
            weekResultInfoVO.setEndTime(byId1.getEndTime());
            return new ApiResponse<WeekResultInfoVO>(Collections.singleton(weekResultInfoVO));
        }

    }
